package com.sh.struts;


/**
 * Copyright (C) 2015 Ari C.
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.content.Context;
import android.widget.Filter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sh.utils.SPUtils;

import java.lang.reflect.Type;
import java.util.*;

public class DataHelper {

    private static final String TITLES_KEY = "search_history_key";

    private static List<ProductWrapper> productWrappers = new ArrayList<>();

    private static List<ProductSearchSuggestion> productSearchSuggestions = new ArrayList<>();

    public interface OnFindTitlesListener {
        void onResults(List<ProductWrapper> results);
    }

    public interface OnFindSuggestionsListener {
        void onResults(List<ProductSearchSuggestion> results);
    }

    public static List<ProductSearchSuggestion> getHistory(Context context, int count) {

        List<ProductSearchSuggestion> suggestionList = new ArrayList<>();
        ProductSearchSuggestion searchSuggestion;
        for (int i = 0; i < productSearchSuggestions.size(); i++) {
            searchSuggestion = productSearchSuggestions.get(i);
            searchSuggestion.setHistory(true);
            suggestionList.add(searchSuggestion);
            if (suggestionList.size() == count) {
                break;
            }
        }
        return suggestionList;
    }

    public static void resetSuggestionsHistory() {
        for (ProductSearchSuggestion searchSuggestion : productSearchSuggestions) {
            searchSuggestion.setHistory(false);
        }
    }

    public static void findSuggestions(Context context, String query, final int limit, final long simulatedDelay,
                                       final OnFindSuggestionsListener listener) {
        new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                try {
                    Thread.sleep(simulatedDelay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                DataHelper.resetSuggestionsHistory();
                List<ProductSearchSuggestion> suggestionList = new ArrayList<>();
                if (!(constraint == null || constraint.length() == 0)) {

                    for (ProductSearchSuggestion suggestion : productSearchSuggestions) {
                        if (suggestion.getBody().toUpperCase()
                                .startsWith(constraint.toString().toUpperCase())) {

                            suggestionList.add(suggestion);
                            if (limit != -1 && suggestionList.size() == limit) {
                                break;
                            }
                        }
                    }
                }

                FilterResults results = new FilterResults();
                Collections.sort(suggestionList, new Comparator<ProductSearchSuggestion>() {
                    @Override
                    public int compare(ProductSearchSuggestion lhs, ProductSearchSuggestion rhs) {
                        return lhs.isHistory() ? -1 : 0;
                    }
                });
                results.values = suggestionList;
                results.count = suggestionList.size();

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                if (listener != null) {
                    listener.onResults((List<ProductSearchSuggestion>) results.values);
                }
            }
        }.filter(query);

    }


    public static void findTitles(Context context, String query, final OnFindTitlesListener listener) {
        initTitleWrapperList(context);

        new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {


                List<ProductWrapper> suggestionList = new ArrayList<>();

                if (!(constraint == null || constraint.length() == 0)) {

                    for (ProductWrapper productWrapper : productWrappers) {
                        if (productWrapper.getTitle().toUpperCase()
                                .startsWith(constraint.toString().toUpperCase())) {

                            suggestionList.add(productWrapper);
                        }
                    }

                }

                FilterResults results = new FilterResults();
                results.values = suggestionList;
                results.count = suggestionList.size();

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                if (listener != null) {
                    listener.onResults((List<ProductWrapper>) results.values);
                }
            }
        }.filter(query);

    }

    private static void initTitleWrapperList(Context context) {
        if (productWrappers == null) {
            productWrappers = new ArrayList<>();
        }
        if (productWrappers.isEmpty()) {
            String jsonString = loadJson(context);
            productWrappers = deserializeTitles(jsonString);
        }
    }

    private static String loadJson(Context context) {
        String jsonString = (String) SPUtils.get(context, TITLES_KEY, "[]");
        return jsonString;
    }

    private static List<ProductWrapper> deserializeTitles(String jsonString) {

        Gson gson = new Gson();

        Type collectionType = new TypeToken<List<ProductWrapper>>() {
        }.getType();
        return gson.fromJson(jsonString, collectionType);
    }

    public static void addHistory(String query) {
        productSearchSuggestions.add(new ProductSearchSuggestion(query));
    }

}
